function [schidx,nsidx] = StimulusAutoshaping(sch,schidx)
% [schidx,nsidx] = StimulusAutoshaping(sch,schidx)
%
%  Extend stimulus delay (stim_delay) and response window by adaptive
%  procedure.
%  
%  If correct response, increment stim_delay by DELAY_STEP, otherwise
%  decrement stim_delay by DELAY_STEP.  Delay boundaries are set by
%  DELAY_MIN and DELAY_MAX. Initial delay is set by DELAY_START and the
%  number of correct responses in a row to increment stim_delay is set by
%  DELAY_ADV.
%
%  Use the following parameters in schedule.writeparams including *
%  ('Write' or 'Read/Write' functionality in ScheduleMaker):
% 

%  Takes the schedule and schidx as input.
%       SCH is the schedule structure
%       SCHIDX is a 1D matrix with the number of rows equal to the number
%           of unique trials; i.e. size(trials,1).
%  Returns an updated version of SCHIDX and NSIDX
%       NSIDX is the next schedule trial index, i.e. the next index
%           selected from the SCH.trials matrix to run.
%       SCHIDX should be updated with the number of runs for each unique
%           trial in SCH.trials.  The returned version should have
%           SCHIDX(NSIDX) incremented.
%
%  This same format for input and output paramters must be met for custom
%  trial select functions (i.e., experiment.trialselectfcn);
%
%  DJS (c) 2011

global G_RP

% some constants
DELAY_START = 1000;  % ms
DELAY_STEP  = 250;  % ms
DELAY_ADV   = 2;    % #correct responses until step
DELAY_MIN   = 1000;  % ms
DELAY_MAX   = 8000; % ms

boxid = sch.boxid;

% find some paramters
% sdidx = findincell(strfind(sch.readparams,'stim_delay'))+1;
rvidx = findincell(strfind(sch.readparams,'response_code'))+1;
RV = sch.response_vals;

trials = sch.trials;

% which module?
writemod = sch.writemodule(1);
RP = G_RP(writemod);

% for training purposes, only use the one schedule row index
nsidx = 1;

% initialize first trial
if isempty(RV)
    schidx = zeros(size(trials,1),1); % initialize SCHIDX
    schidx(nsidx) = 1;
    RP.SetTagVal(sprintf('stim_delay~%d', boxid),DELAY_START);
    return
end

SD = RP.GetTagVal(sprintf('stim_delay~%d', boxid)); % last stimulus delay

% last N responses during response window (light on)
if size(RV,1) >= DELAY_ADV
    if all(bitget(RV(end-DELAY_ADV+1:end,rvidx),9))
        SD = SD + DELAY_STEP;
        
    elseif ~any(bitget(RV(end-DELAY_ADV+1:end,rvidx),9))
        SD = SD - DELAY_STEP;
        
    end
end

% Add some jitter to delay
a = SD - 500; b = SD + 500;
SD = round(a + (b - a) .* rand(1));

% respect bounds
if SD > DELAY_MAX, SD = DELAY_MAX; end
if SD < DELAY_MIN, SD = DELAY_MIN; end

% Update RPvds Tags
RP.SetTagVal(sprintf('stim_delay~%d', boxid),SD);

fprintf('BOX %d: STIM DELAY = %1.0f\n',boxid,SD)


% update SCHIDX
schidx(nsidx) = schidx(nsidx) + 1;









